package com.hbzhou.open.flowcamera;

import com.hbzhou.open.flowcamera.listener.CaptureListener;
import com.hbzhou.open.flowcamera.listener.ClickListener;
import com.hbzhou.open.flowcamera.listener.ReturnListener;
import com.hbzhou.open.flowcamera.listener.TypeListener;
import com.hbzhou.open.flowcamera.util.LogUtil;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Image;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Text;
import ohos.agp.components.element.Element;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.global.configuration.Configuration;

public class CaptureLayout extends StackLayout {
    private CaptureListener mCaptureListener; // 拍照按钮监听
    private TypeListener mTypeListener; // 拍照或录制后接结果按钮监听
    private ReturnListener returnListener; // 退出按钮监听
    private ClickListener mLeftClickListener; // 左边按钮监听
    private ClickListener mRightClickListener; // 右边按钮监听

    private CaptureButton mBtn_capture; // 拍照按钮
    private TypeButton mBtn_confirm; // 确认按钮
    private TypeButton mBtn_cancel; // 取消按钮
    private ReturnButton mBtn_return; // 返回按钮
    private Image mIv_custom_left; // 左边自定义按钮
    private Image mIv_custom_right; // 右边自定义按钮
    private Text mTxt_tip; // 提示文本

    private int mLayout_width;
    private int mLayout_height;

    private int mButton_size;
    private int mIconLeft = 0;
    private int mIconRight = 0;
    private Element mLeftElement;
    private Element mRightElement;

    private boolean isFirst = true;
    private boolean isFromEndByRecord = false;

    public void setTypeListener(TypeListener typeListener) {
        this.mTypeListener = typeListener;
    }

    public void setCaptureListener(CaptureListener captureListener) {
        this.mCaptureListener = captureListener;
    }

    public void setReturnListener(ReturnListener returnListener) {
        this.returnListener = returnListener;
    }

    public CaptureLayout(Context context) {
        this(context, null);
    }

    public CaptureLayout(Context context, AttrSet attrs) {
        this(context, attrs, null);
    }

    public CaptureLayout(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        DisplayAttributes displayAttributes =
                DisplayManager.getInstance().getDefaultDisplay(getContext()).get().getAttributes();
        int screenWidth = displayAttributes.width;
        if (getResourceManager().getConfiguration().direction == Configuration.DIRECTION_VERTICAL) {
            mLayout_width = screenWidth;
        } else {
            mLayout_width = screenWidth / 2;
        }

        mButton_size = (int) (mLayout_width / 4.5f);
        mLayout_height = mButton_size + (mButton_size / 5) * 2 + 100;

        initView();
        initEvent();
    }

    public void initEvent() {
        // 默认Typebutton为隐藏
        mIv_custom_right.setVisibility(HIDE);
        mBtn_cancel.setVisibility(HIDE);
        mBtn_confirm.setVisibility(HIDE);
    }

    public void startTypeBtnAnimator() {
        LogUtil.info(LogUtil.DEFAULT_TAG, "startTypeBtnAnimator");
        // 拍照录制结果后的动画
        if (mIv_custom_left.getVisibility() == VISIBLE) {
            mIv_custom_left.setVisibility(HIDE);
        }
        if (mIv_custom_right.getVisibility() == VISIBLE) {
            mIv_custom_right.setVisibility(HIDE);
        }
        mBtn_return.setVisibility(HIDE);
        mBtn_capture.setVisibility(HIDE);
        mBtn_cancel.setVisibility(VISIBLE);
        mBtn_confirm.setVisibility(VISIBLE);
        mBtn_cancel.setClickable(false);
        mBtn_confirm.setClickable(false);

        AnimatorProperty propertyO = new AnimatorProperty();
        propertyO.moveFromX(mLayout_width / 2f);
        propertyO.moveToX(mButton_size / 2f);
        propertyO.setTarget(mBtn_cancel);

        AnimatorProperty propertyT = new AnimatorProperty();
        propertyT.moveFromX(mLayout_width / 2f);
        propertyT.moveToX(mLayout_width / 2f + mButton_size / 2f);
        propertyT.setTarget(mBtn_confirm);

        startAnimator(propertyO, propertyT);
    }

    private void startAnimator(AnimatorProperty propertyO, AnimatorProperty propertyT) {
        AnimatorGroup animatorGroup = new AnimatorGroup();
        animatorGroup.runParallel(propertyO, propertyT);
        animatorGroup.setStateChangedListener(
                new Animator.StateChangedListener() {
                    @Override
                    public void onStart(Animator animator) {
                        mBtn_cancel.setClickable(true);
                        mBtn_confirm.setClickable(true);
                    }

                    @Override
                    public void onStop(Animator animator) {
                        mBtn_cancel.setClickable(true);
                        mBtn_confirm.setClickable(true);
                    }

                    @Override
                    public void onCancel(Animator animator) {
                        mBtn_cancel.setClickable(true);
                        mBtn_confirm.setClickable(true);
                    }

                    @Override
                    public void onEnd(Animator animator) {
                        mBtn_cancel.setClickable(true);
                        mBtn_confirm.setClickable(true);
                    }

                    @Override
                    public void onPause(Animator animator) {
                        mBtn_cancel.setClickable(true);
                        mBtn_confirm.setClickable(true);
                    }

                    @Override
                    public void onResume(Animator animator) {
                    }
                });
        animatorGroup.setDuration(300);
        animatorGroup.start();
    }

    private void initView() {
        addBtnCaptureEvent();
        addBtnCancelEvent();
        addBtnConfirmEvent();
        addBtnReturnEvent();
        addCustomLeftEvent();
        addCustomRightEvent();
        addTextEvent();

        this.addComponent(mBtn_capture);
        this.addComponent(mBtn_cancel);
        this.addComponent(mBtn_confirm);
        this.addComponent(mBtn_return);
        this.addComponent(mIv_custom_left);
        this.addComponent(mIv_custom_right);
        this.addComponent(mTxt_tip);
    }

    private void addBtnCaptureEvent() {
        // 拍照按钮
        mBtn_capture = new CaptureButton(getContext(), mButton_size);
        int outsideAddSize = mButton_size / 5;
        int width = mButton_size + outsideAddSize * 2;
        int height = mButton_size + outsideAddSize * 2;

        LayoutConfig config = new LayoutConfig(width, height);
        config.alignment = LayoutAlignment.CENTER;
        mBtn_capture.setLayoutConfig(config);
        addBtnCaptureCallback();
    }

    private void addTextEvent() {
        mTxt_tip = new Text(getContext());
        LayoutConfig txtParam = new LayoutConfig(LayoutConfig.MATCH_CONTENT, LayoutConfig.MATCH_CONTENT);
        txtParam.alignment = LayoutAlignment.HORIZONTAL_CENTER;
        txtParam.setMargins(0, 0, 0, 0);
        mTxt_tip.setLayoutConfig(txtParam);
        mTxt_tip.setTextSize(36);
        mTxt_tip.setText("轻触拍照，长按摄像");
        mTxt_tip.setTextColor(new Color(0xFFFFFFFF));
    }

    private void addCustomRightEvent() {
        // 右边自定义按钮
        mIv_custom_right = new Image(getContext());

        LayoutConfig ivCustomParamRight = new LayoutConfig((int) (mButton_size / 2.5f), (int) (mButton_size / 2.5f));
        ivCustomParamRight.alignment = LayoutAlignment.VERTICAL_CENTER | LayoutAlignment.RIGHT;
        ivCustomParamRight.setMargins(0, 0, mLayout_width / 6, 0);
        mIv_custom_right.setLayoutConfig(ivCustomParamRight);

        mIv_custom_right.setClickedListener(
                component -> {
                    if (mRightClickListener != null) {
                        mRightClickListener.onClick();
                    }
                });
    }

    private void addCustomLeftEvent() {
        // 左边自定义按钮
        mIv_custom_left = new Image(getContext());

        LayoutConfig ivCustomParamLeft = new LayoutConfig((int) (mButton_size / 2.5f), (int) (mButton_size / 2.5f));
        ivCustomParamLeft.alignment = LayoutAlignment.VERTICAL_CENTER;
        ivCustomParamLeft.setMargins(mLayout_width / 6, 0, 0, 0);
        mIv_custom_left.setLayoutConfig(ivCustomParamLeft);
        mIv_custom_left.setClickedListener(
                component -> {
                    if (mLeftClickListener != null) {
                        mLeftClickListener.onClick();
                    }
                });
    }

    private void addBtnReturnEvent() {
        // 返回按钮
        int btnReturnSize = (int) (mButton_size / 2.5f);
        mBtn_return = new ReturnButton(getContext(), btnReturnSize);

        LayoutConfig btnReturnParam = new LayoutConfig(btnReturnSize, btnReturnSize / 2);
        btnReturnParam.alignment = LayoutAlignment.VERTICAL_CENTER;
        btnReturnParam.setMargins(mLayout_width / 6, 0, 0, 0);
        mBtn_return.setLayoutConfig(btnReturnParam);

        mBtn_return.setClickedListener(
                component -> {
                    if (mLeftClickListener != null) {
                        mLeftClickListener.onClick();
                    }
                });
    }

    private void addBtnConfirmEvent() {
        // 确认按钮
        mBtn_confirm = new TypeButton(getContext(), TypeButton.TYPE_CONFIRM, mButton_size);
        LayoutConfig btnConfirmParam = new LayoutConfig(mButton_size, mButton_size);
        btnConfirmParam.alignment = LayoutAlignment.CENTER;
        mBtn_confirm.setLayoutConfig(btnConfirmParam);
        mBtn_confirm.setClickedListener(
                component -> {
                    if (mTypeListener != null) {
                        mTypeListener.confirm(isFromEndByRecord);
                    }
                    isFromEndByRecord = false;
                    startAlphaAnimation();
                });
    }

    private void addBtnCancelEvent() {
        // 取消按钮
        mBtn_cancel = new TypeButton(getContext(), TypeButton.TYPE_CANCEL, mButton_size);

        LayoutConfig btnCancelParam = new LayoutConfig(mButton_size, mButton_size);
        btnCancelParam.alignment = LayoutAlignment.CENTER;
        mBtn_cancel.setLayoutConfig(btnCancelParam);
        mBtn_cancel.setClickedListener(
                component -> {
                    if (mTypeListener != null) {
                        mTypeListener.cancel(isFromEndByRecord);
                    }
                    isFromEndByRecord = false;
                    startAlphaAnimation();
                });
    }

    private void addBtnCaptureCallback() {
        if (mBtn_capture == null) {
            return;
        }
        mBtn_capture.setCaptureListener(
                new CaptureListener() {
                    @Override
                    public void takePictures() {
                        isFromEndByRecord = false;
                        if (mCaptureListener != null) {
                            mCaptureListener.takePictures();
                        }
                    }

                    @Override
                    public void recordShort(long time) {
                        if (mCaptureListener != null) {
                            mCaptureListener.recordShort(time);
                        }
                        startAlphaAnimation();
                    }

                    @Override
                    public void recordStart() {
                        if (mCaptureListener != null) {
                            mCaptureListener.recordStart();
                        }
                        startAlphaAnimation();
                    }

                    @Override
                    public void recordEnd(long time) {
                        isFromEndByRecord = true;
                        if (mCaptureListener != null) {
                            mCaptureListener.recordEnd(time);
                        }
                        startAlphaAnimation();
                        startTypeBtnAnimator();
                    }

                    @Override
                    public void recordZoom(float zoom) {
                        if (mCaptureListener != null) {
                            mCaptureListener.recordZoom(zoom);
                        }
                    }

                    @Override
                    public void onError(String errorMessage, int type) {
                        if (mCaptureListener != null) {
                            mCaptureListener.onError(errorMessage, type);
                        }
                    }
                });
    }


    public void resetCaptureLayout() {
        mBtn_capture.resetState();
        mBtn_cancel.setVisibility(HIDE);
        mBtn_confirm.setVisibility(HIDE);
        mBtn_capture.setVisibility(VISIBLE);
        if (this.mIconLeft != 0 || mLeftElement != null) {
            mIv_custom_left.setVisibility(VISIBLE);
            mBtn_return.setVisibility(VISIBLE);
        } else {
            mBtn_return.setVisibility(VISIBLE);
        }
        if (this.mIconRight != 0 || mRightElement != null) {
            mIv_custom_right.setVisibility(VISIBLE);
        }
    }

    public void startAlphaAnimation() {
        if (isFirst) {
            AnimatorProperty animatorTxtTip = new AnimatorProperty(mTxt_tip);
            animatorTxtTip.alpha(1f).alpha(0f);
            animatorTxtTip.setDuration(500);
            animatorTxtTip.start();
            isFirst = false;
        }
    }

    public void setTextWithAnimation(String tip) {
        mTxt_tip.setText(tip);
        AnimatorProperty animatorTxtTip = new AnimatorProperty(mTxt_tip);
        animatorTxtTip.alpha(0f).alpha(1f).alpha(1f).alpha(0f);
        animatorTxtTip.setDuration(2500);
        animatorTxtTip.start();
    }

    public void setDuration(int duration) {
        mBtn_capture.setDuration(duration);
    }

    public void setButtonColor(int in_color, int out_color, int progress_color) {
        mBtn_capture.setButtonCircleColor(in_color, out_color, progress_color);
    }

    public void setButtonFeatures(int state) {
        mBtn_capture.setButtonFeatures(state);
    }

    public void setTip(String tip) {
        mTxt_tip.setText(tip);
    }

    public void showTip() {
        mTxt_tip.setVisibility(VISIBLE);
    }

    public void setIconSrc(Element leftElement, Element rightElement) {
        this.mLeftElement = leftElement;
        this.mRightElement = rightElement;
        if (leftElement != null) {
            mIv_custom_left.setImageElement(leftElement);
            mIv_custom_left.setVisibility(VISIBLE);
        } else {
            mIv_custom_left.setVisibility(HIDE);
        }
        mBtn_return.setVisibility(VISIBLE);
        if (rightElement != null) {
            mIv_custom_right.setImageElement(rightElement);
            mIv_custom_right.setVisibility(VISIBLE);
        } else {
            mIv_custom_right.setVisibility(HIDE);
        }
    }

    public void setIconSrc(int iconLeft, int iconRight) {
        this.mIconLeft = iconLeft;
        this.mIconRight = iconRight;
        if (this.mIconLeft != 0) {
            mIv_custom_left.setPixelMap(iconLeft);
            mIv_custom_left.setVisibility(VISIBLE);
        } else {
            mIv_custom_left.setVisibility(HIDE);

        }
        mBtn_return.setVisibility(VISIBLE);
        if (this.mIconRight != 0) {
            mIv_custom_right.setPixelMap(iconRight);
            mIv_custom_right.setVisibility(VISIBLE);
        } else {
            mIv_custom_right.setVisibility(HIDE);
        }
    }

    public void setLeftClickListener(ClickListener leftClickListener) {
        this.mLeftClickListener = leftClickListener;
    }

    public void setRightClickListener(ClickListener rightClickListener) {
        this.mRightClickListener = rightClickListener;
    }
}
